#!/usr/bin/python
# -*- coding: utf-8 -*-
# @version        : 1.0
# @Create Time    : 2024/9/6 11:11
# @File           : vendor
# @IDE            : PyCharm
# @desc           : 描述

from enum import Enum
from uuid import uuid4
from typing import List, Optional, Union
from typing_extensions import Annotated
from core.data_types import DatetimeStr
from pydantic import (AfterValidator, BaseModel, ConfigDict, Field, PlainSerializer, 
                      WithJsonSchema, computed_field, field_validator)


class QARContentTypeEnum(Enum):
    insp = '检验项目'
    test = '实验要求'
    limit = '限制要求'


class QARFemaleBase(BaseModel):
    version: Optional[int] = 1
    status: Optional[str] = None

    part_no: str
    part_name: Optional[str] = None
    part_type: Optional[str] = None
    material_no: Optional[str] = None

    rev_letter: Optional[str] = None
    temper: Optional[str] = None
    zpm_cpm: Optional[str] = None
    typing: Optional[str] = None
    classing: Optional[str] = None
    grade: Optional[str] = None
    form: Optional[str] = None
    size: Optional[str] = None
    color: Optional[str] = None
    material_type: Optional[str] = None

    product_type: Optional[str] = None
    spec_stan: Optional[str] = None
    spec_stan_rev: Optional[str] = None

    mat_code: Optional[str] = None
    test_items: Optional[str] = None
    required_dimension: Optional[str] = None
    pclr_quantity: Optional[str] = None
    pclr_size: Optional[str] = None

    plan_remark: Optional[str] = None
    life_limit_req: Optional[str] = None
    life_limit_date: Optional[DatetimeStr] = None
    life_limit_period: Optional[str] = None
    life_limit_manage: Optional[str] = None
    
    is_sampling: Optional[bool] = None

    special_property: Optional[str] = None
    manufacturer: Optional[str] = None
    change_no: Optional[str] = None
    draw_no: Optional[str] = None
    draw_no_rev: Optional[str] = None
    software_code: Optional[str] = None
    software_rev: Optional[str] = None
    atp_no: Optional[str] = None


    is_life_limit: Optional[bool] = None
    is_correct_order: Optional[bool] = None

    remark: Optional[str] = None

    create_user: Optional[str] = None
    update_user: Optional[str] = None


class QARFemale(QARFemaleBase):
    is_insp: Optional[bool] = None
    is_test: Optional[bool] = None


class QARFemaleSimpleOut(QARFemale):
    model_config = ConfigDict(from_attributes=True)

    id: int

    update_datetime: DatetimeStr
    create_datetime: DatetimeStr


# 实现自定义一个日期时间字符串的数据类型
StrList = Annotated[
    Union[str, List],
    AfterValidator(lambda x: x.split(";") if isinstance(x, str) else x),
    PlainSerializer(lambda x: x, return_type=list),
    WithJsonSchema({'type': 'list'}, mode='serialization')
]


class QARFemaleContentItem(BaseModel):
    model_config = ConfigDict(from_attributes=True)
    id: Optional[str] = Field(default_factory=lambda: uuid4().hex)

    content_type: Optional[str] = None
    project: Optional[str] = None
    detail: Optional[StrList] = []

    detail_value: Optional[StrList] = []
    attachment: Optional[str] = None
    remark: Optional[str] = None

    check: Optional[bool] = False
    is_pass: Optional[bool] = None


class QARFemaleContentChild(QARFemaleContentItem):
    model_config = ConfigDict(from_attributes=True)

    children: Optional[List[QARFemaleContentItem]] = []


class QARFemaleContent(QARFemaleContentChild):
    model_config = ConfigDict(from_attributes=True)


class QARFemaleFeature(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    part_no: str
    characteristic: str
    dimension: str

    irr: Optional[str]
    grade: Optional[str]
    
    count: Optional[str]

    check: Optional[bool] = False


class QARFemaleIn(QARFemaleBase):
    model_config = ConfigDict(from_attributes=True)

    contents: List[QARFemaleContent] = []
    asr_features: List[QARFemaleFeature] = []

    @field_validator('contents')
    def parse_contents(cls, v):
        def clean_tree(node):    
            if not node:
                return None
            
            if not node.project:
                return None
            if isinstance(node, QARFemaleContent):
                filter_children = [clean_tree(child) for child in node.children]
                filter_children = [child for child in filter_children if child]
                node.children = filter_children

            return node

        v = [clean_tree(i) for i in v]
        return [i for i in v if v]

    @computed_field
    def is_insp(self) -> bool:
        for item in self.asr_features:
            if item.check:
                return True
        return False
    
    @computed_field
    def is_test(self) -> bool:
        for item in self.contents:
            if item.check:
                return True
        return False

class QARFemaleOut(QARFemaleSimpleOut):
    model_config = ConfigDict(from_attributes=True)

    contents: Optional[List[QARFemaleContent]] = []
    asr_features: Optional[List[QARFemaleFeature]] = []